#include "RTC.h"

__IO uint32_t TimeDisplay = 0;
__IO uint8_t incomingByte[6] = {0,0,0,0,0,0};
void RTCInitController(void){
	NVIC_InitTypeDef NVIC_InitStructure;

	/* Configure one bit for preemption priority */
	NVIC_PriorityGroupConfig(RTC_PREEMPTION);

	/* Enable the RTC Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = RTC_PREEMPTION;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = RTC_SUB_PRIORITY;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
	{
	/* Backup data register value is not correct or not yet programmed (when
	   the first time the program is executed) */

	printf("\r\n\n RTC not yet configured....");

	/* RTC Configuration */
	RTC_Configuration();

	printf("\r\n RTC configured....");

	/* Adjust time by values entred by the user on the hyperterminal */
	Time_Adjust();

	BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
	}
	else
	{
	/* Check if the Power On Reset flag is set */
	if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
	{
	  printf("\r\n\n Power On Reset occurred....");
	}
	/* Check if the Pin Reset flag is set */
	else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
	{
	  printf("\r\n\n External Reset occurred....");
	}

	printf("\r\n No need to configure RTC....");
	/* Wait for RTC registers synchronization */
	RTC_WaitForSynchro();

	/* Enable the RTC Second */
	RTC_ITConfig(RTC_IT_SEC, ENABLE);
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
	}
}


void RTC_Configuration(void){

	/* Enable PWR and BKP clock */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

	/* Enable WKUP pin */
	PWR_WakeUpPinCmd(ENABLE);

	/* Allow access to BKP Domain */
	PWR_BackupAccessCmd(ENABLE);

	/* Check if the StandBy flag is set */
	if(PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)
	{/* System resumed from STANDBY mode */

	/* Turn on LED2 */
	LedOn(LED0);

	/* Clear StandBy flag */
	PWR_ClearFlag(PWR_FLAG_SB);

	/* Wait for RTC APB registers synchronisation */
	RTC_WaitForSynchro();
	/* No need to configure the RTC as the RTC configuration(clock source, enable,
	prescaler,...) is kept after wake-up from STANDBY */
	}
	else
	{/* StandBy flag is not set */

	/* RTC clock source configuration ----------------------------------------*/
	/* Reset Backup Domain */
	BKP_DeInit();

	/* Enable LSE */
	RCC_LSEConfig(RCC_LSE_ON);
	/* Wait till LSE is ready */
	while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
	{}

	/* Select LSE as RTC Clock Source */
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

	/* Enable RTC Clock */
	RCC_RTCCLKCmd(ENABLE);

	/* Wait for RTC registers synchronization */
	RTC_WaitForSynchro();

	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();

	/* Enable the RTC Second */
	RTC_ITConfig(RTC_IT_SEC, ENABLE);

	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();

	/* Set RTC prescaler: set RTC period to 1sec */
	RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
}

/**
  * @brief  Gets numeric values from the hyperterminal.
  * @param  None
  * @retval None
  */

uint32_t Time_Regulate(void){
	uint32_t Tmp_HH = 0xFF, Tmp_MM = 0xFF, Tmp_SS = 0xFF;
	
	uint8_t incomingByte_position = 0;
	uint8_t VTimerID_clearbuffer = 0;
	uint8_t clearbuffer_flag = 0;
	uint8_t i;
	printf("\r\n==============Time Settings=====================================");
	printf("\r\n  Please Set Hours");
	VTimerID_clearbuffer = VTimerGetID();
	while (Tmp_HH == 0xFF || Tmp_MM==0xFF || Tmp_SS==0xFF){
		if (UART_DEBUG_RXAvailable()){
			incomingByte[incomingByte_position] = UART_DEBUG_ReceivedByte();
			incomingByte_position ++;
			VTimerSet(VTimerID_clearbuffer,100);
		}
		if(VTimerIsFired(VTimerID_clearbuffer)){		//kiem tra timeout
			if (incomingByte_position != 6 ){		// nhan chua du 6 byte
				incomingByte_position = 0;
				for ( i = 0;i<6;i++){
					incomingByte[i] = 0;					
				}			
			}
		}		
		for (i=0;i<6;i++){
			if (incomingByte[i]>='0' && incomingByte[i]<='9'){
			Tmp_HH = (incomingByte[0]-'0')*10 + (incomingByte[1]-'0');
			Tmp_MM = (incomingByte[2]-'0')*10 + (incomingByte[3]-'0');
			Tmp_SS = (incomingByte[4]-'0')*10 + (incomingByte[5]-'0');
			}
			else {
				Tmp_HH = 0xFF;
				Tmp_MM==0xFF;
				Tmp_SS==0xFF;
			}
		}
	}
	return((Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS));
}

void Time_Adjust(void){
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
	/* Change the current time */
	RTC_SetCounter(Time_Regulate());
	/* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
}
void Time_Show(void)
{
	Time_Display(RTC_GetCounter());
}
void Time_Display(uint32_t TimeVar)
{
  uint32_t THH = 0, TMM = 0, TSS = 0;
  
  /* Reset RTC Counter when Time is 23:59:59 */
  if (RTC_GetCounter() == 0x0001517F)
  {
     RTC_SetCounter(0x0);
     /* Wait until last write operation on RTC registers has finished */
     RTC_WaitForLastTask();
  }
  
  /* Compute  hours */
  THH = TimeVar / 3600;
  /* Compute minutes */
  TMM = (TimeVar % 3600) / 60;
  /* Compute seconds */
  TSS = (TimeVar % 3600) % 60;

  printf("Time: %0.2d:%0.2d:%0.2d\r", THH, TMM, TSS);
}

void RTC_ISR(){
	if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
	{
		/* Clear the RTC Second interrupt */
		RTC_ClearITPendingBit(RTC_IT_SEC);

		/* Enable time update */
		//TimeDisplay = 1;

		/* Wait until last write operation on RTC registers has finished */
		RTC_WaitForLastTask();    
	}
}


